package com.msun.auth.custom.exception;
//GlobalExceptionAdvice

import com.msun.auth.custom.packdto.BizResponse;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * 全局异常处理类
 *
 * @author guijie
 * @RestControllerAdvice(@ControllerAdvice)，拦截异常并统一处理
 */
@RestControllerAdvice
public class GlobalExceptionAdvice {

    /**
     * 参数绑定异常
     *
     * @param e 异常
     * @return 异常结果
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public BizResponse<?> handleBindException(BindException e) {
        e.printStackTrace();
        return new BizResponse<>(BizResultCode.Error.getCode(), "参数绑定异常", null);
    }

    /**
     * 参数缺失类型解析异常
     *
     * @param e 异常
     * @return 异常结果
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public BizResponse<?> handleMethodArgumentTypeMismatchException(BindException e) {
        e.printStackTrace();
        return new BizResponse<>(BizResultCode.Error.getCode(), "参数缺失类型解析异常", null);
    }


    /**
     * @Description: valid抛出的异常处理
     **/
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public BizResponse<?> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        e.printStackTrace();
        BizResultCode code = BizResultCode.ArgumentNotValid;
        List<String> arr = new ArrayList<>();
        for (ObjectError error : e.getBindingResult().getAllErrors()) {
            //获取校验的信息
            arr.add(error.getDefaultMessage());
        }
        // 封装成自己固定的格式
        return new BizResponse<>().failWithMessage(code,String.join(",", arr), e);
    }

    /**
     * @Description: 自定义异常抛出统一处理
     **/
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = BizException.class)
    @ResponseBody
    public BizResponse<?> bizExceptionHandler(BizException e) {
        if (e.getE() != null) {
            e.getE().printStackTrace();
        }
        // 封装成自己固定的格式
        return new BizResponse<>(e.getCode(), e.getMessage(), null);
    }

    /**
     * @Description: 其他异常
     **/
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Throwable.class)
    @ResponseBody
    public BizResponse<?> throwableHandle(Throwable e, HttpServletRequest request) {
        e.printStackTrace();
        BizResultCode code = BizResultCode.Error;
        return new BizResponse<>().fail(code, e);
    }
}
